# -*- coding: UTF-8 -*-

import threading
import socket
from chat.common.RSA_file import message_decryption
from chat.common.OTP import OTP_decryption
from chat.client.client_database import *
import chat.client.gol
import struct


class recver_thread(threading.Thread):  # 继承父类threading.Thread
    def __init__(self):
        threading.Thread.__init__(self)

    def run(self):  # 把要执行的代码写到run函数里面 线程在创建后会直接运行run函数
        username = chat.client.gol.get_value("socket_username")
        s = socket.socket(socket.AF_INET6, socket.SOCK_STREAM)
        s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        s.bind(('::1', 2335))
        s.listen(1)

        chat.client.gol.get_value("socket_obj").send("SUCCESS".encode())
        while True:
            server, address = s.accept()
            data_len = server.recv(4)
            data_len = int.from_bytes(data_len, 'little')
            data_type = server.recv(4)
            data_type = int.from_bytes(data_type, 'little')
            if data_type == 4:  # room
                username = chat.client.gol.get_value("socket_username")
                print("recver.29", username)
                d = int(return_user_pkey(username))
                n = int(return_user_pkey_n(username))
                print("hello")

                data = message_decryption(server.recv(data_len).decode(), d, n).encode()
                # data = server.recv(data_len)

                data_head = data[0:16]
                room_id, len_pbk, len_pvk, len_n, len_room_name = struct.unpack("<HiiiH", data_head)
                print("room_id ==>", room_id)
                pbk = int(bytes.decode(data[16:16 + len_pbk]))
                pvk = int(bytes.decode(data[16 + len_pbk:16 + len_pbk + len_pvk]))
                n = int(bytes.decode(data[16 + len_pbk + len_pvk:16 + len_pbk + len_pvk + len_n]))
                room_name = bytes.decode(
                    data[16 + len_pbk + len_pvk + len_n:16 + len_pbk + len_pvk + len_n + len_room_name])

                print(">>>", pbk, pvk, n, room_name)
                # 存本地数据库
                update_user_room(username, room_id, room_name, pvk, n, pbk)

            elif data_type == 5:  # 发送消息
                data_head = server.recv(12)
                room_id, sender_id, msg_len = struct.unpack("<HHQ", data_head)
                enc_msg = server.recv(msg_len).decode()

                flag = server.recv(1)
                OTP_flag = int.from_bytes(flag, 'little')

                username = chat.client.gol.get_value("socket_username")
                print("test2>>", username)
                d = int(return_room_private_key(username, room_id))
                n = int(return_room_private_key_n(username, room_id))
                real_msg = message_decryption(enc_msg, d, n)
                if OTP_flag == 1:
                    if chat.client.gol.get_value("OTP_key") == None:
                        chat.client.gol.set_value("OTP_key","BUPT_Chat_default")
                    real_msg = OTP_decryption(real_msg)

                chat.client.gol.set_value(str(room_id)+"recv_msg_flag", 1)
                chat.client.gol.set_value(str(room_id)+"recv_msg_sender", sender_id)
                chat.client.gol.set_value(str(room_id)+"recv_msg_msg", real_msg)
                print(real_msg)

                # 前端显示

            elif data_type == 6:  # 刷新列表
                print("=========================[刷新rooms]=========================")

                enc_data = server.recv(data_len).decode()
                my_username = chat.client.gol.get_value("socket_username")
                pvkey = int(return_user_pkey(my_username))
                n = int(return_user_pkey_n(my_username))
                data = message_decryption(enc_data, pvkey, n)

                # data_head = server.recv(4)
                user_num, room_num = struct.unpack("<HH", data[0:4].encode())
                user_info = []
                room_info = []
                data = data[4:]

                for i in range(user_num):
                    user_id, username_len = struct.unpack("<HH", data[0:4].encode())
                    username = data[4:4+username_len]
                    user_info.append((user_id, username))
                    data = data[4+username_len:]

                for i in range(room_num):
                    room_id, roomname_len = struct.unpack("<HH", data[0:4].encode())
                    roomname = data[4:4+roomname_len]
                    data = data[4+roomname_len:]
                    room_pbk_len,room_n_len,room_pvk_len = struct.unpack("<iii", data[0:12].encode())
                    data = data[12:]
                    room_pbk = data[0:room_pbk_len]
                    room_n = data[room_pbk_len:room_pbk_len+room_n_len]
                    room_pvk = data[room_pbk_len+room_n_len:room_pbk_len+room_n_len+room_pvk_len]
                    data = data[room_pbk_len+room_n_len+room_pvk_len:]
                    room_info.append((room_id, roomname, room_pbk, room_pvk, room_n))

                    update_user_room(my_username, room_id, roomname, room_pvk, room_n, room_pbk)

                print(user_info)
                print(room_info)
                chat.client.gol.set_value("user_info", user_info)
                chat.client.gol.set_value("room_info", room_info)
                chat.client.gol.set_value("list_change_flag", 1)



            elif data_type == 9:    # 文件接收

                file_head = server.recv(10)
                room_id, sender_id, filename_len, file_size = struct.unpack('<HHHl', file_head)
                filename = server.recv(filename_len).decode()

                print('file new name is {0}, file_size if {1}'.format(str(filename), file_size))

                recvd_size = 0  # 定义已接收文件的大小
                # 存储在该脚本所在目录下面
                fp = open('./' + str(filename), 'wb')
                print('start receiving...')

                # 将分批次传输的二进制流依次写入到文件
                while not recvd_size == file_size:
                    if file_size - recvd_size > 1024:
                        data = server.recv(1024)
                        recvd_size += len(data)
                    else:
                        data = server.recv(file_size - recvd_size)
                        recvd_size = file_size
                    fp.write(data)
                fp.close()
                print('end receive...')

                filename = str(filename)
                path = './upload/'+filename
                # 弹窗提示收到文件filename
